#include "stdafx.h"


DynamicMesh::DynamicMesh(const D3DXVECTOR3& position, const D3DXVECTOR3& size) :
	StaticMesh(position, size),
	mChanged(false),
	mRotation(0, 0, 0)
{
}


DynamicMesh::~DynamicMesh(void)
{
}


void DynamicMesh::fromObjFile(const std::string& file, int firstIndex)
{
	std::vector<Vertex> vertices;
	std::vector<short> indices;
	std::ifstream inFile(file);
	if(inFile.is_open())
	{
		std::string line;
		while(inFile.good())
		{
			std::stringstream ss;
			getline(inFile, line);
			if(line[0] == 'v')
			{
				if(line[1] == 'n')
				{
				}
				else
				{
					Vertex vertex;

					ss << line.substr(2, -1);
					ss >> vertex.x;
					ss >> vertex.y;
					ss >> vertex.z;
					vertex.x += mSize.x * mPosition.x;
					vertex.y += mSize.y * mPosition.y;
					vertex.z += mSize.z * mPosition.z;
					vertices.push_back(vertex);
				}
			}
			else if(line[0] == 'f')
			{
				short a;
				std::replace(line.begin(), line.end(), '/', ' ');
				ss << line.substr(2, -1);
				for(int i = 0; i < 3; ++i)
				{
					int normal;
					ss >> a;
					ss >> normal;
					a -= firstIndex; //indices start from 0
					indices.push_back(a);
					std::cout << a << " ";
				}
				std::cout << std::endl;
			}
		}
		auto size = vertices.size() * sizeof(Vertex);
		mNumVertices = vertices.size();

		globals::d3dDevice->CreateVertexBuffer(size, D3DUSAGE_WRITEONLY, Vertex::FVF_Flags, D3DPOOL_DEFAULT, &mVertexBuffer, nullptr);
		void *pVertices;
		mVertexBuffer->Lock( 0, 0, (void**)&pVertices, 0 );

		memcpy( pVertices, &*vertices.begin(), size );
		mVertexBuffer->Unlock();

		size = indices.size() * sizeof(short);
		mNumIndices = indices.size() / 3;

		globals::d3dDevice->CreateIndexBuffer(size, 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &mIndexBuffer, nullptr);
		void* pIndices;
		mIndexBuffer->Lock(0, 0, (void**)&pIndices, 0);

		memcpy(pIndices, &*indices.begin(), size);
		mIndexBuffer->Unlock();
	}
}


void DynamicMesh::render()
{
	D3DXMATRIX matTranslation, matRotation;
	D3DXMATRIX matWorld;

	D3DXMatrixRotationYawPitchRoll(&matRotation, mRotation.x, mRotation.y, mRotation.z);
	D3DXMatrixTranslation(&matTranslation, mPosition.x, mPosition.y, mPosition.z);

	D3DXMatrixMultiply(&matWorld, &matTranslation, &matRotation);
	globals::d3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
	
	globals::d3dDevice->SetStreamSource(0, mVertexBuffer, 0, sizeof(Vertex));
	globals::d3dDevice->SetIndices(mIndexBuffer);

	globals::d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, mNumVertices, 0, mNumIndices);

	globals::d3dDevice->SetTransform(D3DTS_WORLD, &globals::matIdentity);
}


void DynamicMesh::setPosition(const D3DXVECTOR3& position)
{
	mPosition = position;
}


void DynamicMesh::rotate(const D3DXVECTOR3& axis)
{
	mChanged = true;
	mRotation += axis;
}


void DynamicMesh::move(const D3DXVECTOR3& amt)
{
	mChanged = true;
	mPosition += amt;
}


std::string dmfakeGet()
{
	return nullptr;
}


void DynamicMesh::toLua()
{
	using luabind::def;
	using luabind::class_;

	luabind::module(lua::State())
		[
			class_<DynamicMesh>("DynamicMesh").
			def(luabind::constructor<const D3DXVECTOR3&, const D3DXVECTOR3&>()).
			def("render", &DynamicMesh::render).
			def("fromObjFile", &DynamicMesh::fromObjFile).
			def("rotate", &DynamicMesh::rotate).
			def("move", &DynamicMesh::move).
			property("position", &DynamicMesh::getPosition, &DynamicMesh::setPosition).
			property("texture", &dmfakeGet, &DynamicMesh::setTexture)
		];
}